package com.hm.ibsm.api;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hm.common.def.MobileDevicesDef;
import com.hm.common.su.bean.ServerResponse;
import com.hm.common.util.CommonUtil;
import com.hm.common.util.RemoteClientUtil;
import com.hm.common.util.VerifyCodeUtil;
import com.hm.ibsm.auto.ManageProperties;
import com.hm.ibsm.manage.service.AuthService;
import com.hm.ibsm.manage.vo.auth.AuthUserTokenVo;
import com.hm.ibsm.manage.vo.auth.AuthUserVo;
import com.hm.ibsm.manage.vo.auth.RoleMenuVo;
import com.hm.ibsm.manage.vo.auth.UserMenuVo;
import com.hm.ibsm.manage.vo.auth.UserRoleVo;
import com.hm.ibsm.util.ControllerResult;
import com.hm.ibsm.util.R.API;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;

/**
 * @author shishun.wang
 * @date 2017年2月8日 下午5:41:46
 * @version 1.0
 * @describe 授权管理
 */
@Slf4j
@ResponseBody
@RestController
@RequestMapping(API.MODULE_NAME + "/auth")
public class ApiAuth {

	private static final String MODULE_TAG_NAME = "授权管理";

	@Autowired
	private AuthService authService;

	@Autowired
	private ManageProperties manageProperties;

	@RequestMapping(method = RequestMethod.POST)
	@ApiOperation(tags = MODULE_TAG_NAME, value = "用户登录", httpMethod = "POST", notes = "用户登录,登陆成功返回用户基本信息")
	public ResponseEntity<ServerResponse<AuthUserVo>> addUser(
			@ApiParam(required = false, name = "account", value = "账户名") @RequestParam(name = "account", required = false) String account,
			@ApiParam(required = false, name = "email", value = "邮箱") @RequestParam(name = "email", required = false) String email,
			@ApiParam(required = false, name = "mobile", value = "手机号码") @RequestParam(name = "mobile", required = false) String mobile,
			@ApiParam(required = true, name = "pwd", value = "登陆密码") @RequestParam(name = "pwd") String pwd,
			HttpServletRequest request) {
		try {
			if (CommonUtil.isAllEmpty(account, email, mobile)) {
				return ControllerResult.failed("登陆账户名、邮箱、手机号码不能全为空");
			}

			if (CommonUtil.isNotEmpty(account)) {
				return ControllerResult.success(authService.loginByAccountPwd(account, pwd, MobileDevicesDef.PC, RemoteClientUtil.getHost(request)));
			}

			if (CommonUtil.isNotEmpty(email)) {
				return ControllerResult.success(authService.loginByEmailPwd(email, pwd, MobileDevicesDef.PC, RemoteClientUtil.getHost(request)));
			}

			return ControllerResult.success(authService.loginByMobilePwd(mobile, pwd, MobileDevicesDef.PC, RemoteClientUtil.getHost(request)));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/logout", method = RequestMethod.PATCH)
	@ApiOperation(value = "注销用户", httpMethod = "PATCH", notes = "注销用户,退出当前系统", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<Boolean>> logout(HttpServletRequest request) {
		try {
			String tokenId = ControllerResult.currentTokenId(request);
			String secretKey = ControllerResult.currentSecretKey(request);
			return ControllerResult.success(authService.logout(tokenId, secretKey));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/vcode", method = RequestMethod.GET)
	@ApiOperation(value = "获取随机验证码", httpMethod = "GET", notes = "获取随机验证码", tags = MODULE_TAG_NAME)
	public void verifyCode(HttpServletRequest request, HttpServletResponse response,
			@ApiParam(required = true, name = "width", value = "验证码长度") @RequestParam("width") int width,
			@ApiParam(required = true, name = "height", value = "验证码高度") @RequestParam("height") int height,
			@ApiParam(required = true, name = "size", value = "随机数长度") @RequestParam("size") int size) throws Exception {
		if (CommonUtil.isAnyEmpty(width, height, size)) {
			response.getWriter()
					.println(JSON.toJSONString(new ServerResponse<String>().failure("参数错误:width、height、size"), SerializerFeature.WriteMapNullValue));
			return;
		}
		// TODO 验证tokenCode是否存在,

		{// 设置请求响应头
			response.setHeader("Pragma", "No-cache");
			response.setHeader("Cache-Control", "no-cache");
			response.setDateHeader("Expires", 0);
			response.setContentType("image/jpeg");
		}
		String code = VerifyCodeUtil.generateVerifyCode(size);
		VerifyCodeUtil.outputImage(width, height, response.getOutputStream(), code);
	}

	@RequestMapping(value = "/user/roles", method = RequestMethod.POST)
	@ApiOperation(value = "设置用户角色所属列表", httpMethod = "POST", notes = "设置用户角色所属列表", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<Boolean>> setUserRoles(
			@ApiParam(required = true, name = "roles", value = "角色列表") @RequestParam(name = "roles", required = true) List<String> roles,
			HttpServletRequest request) {
		try {
			String userId = authService.loadCurrentUserId(ControllerResult.currentTokenId(request), ControllerResult.currentSecretKey(request));
			return ControllerResult.success(authService.setUserRoles(userId, roles));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/{roleId}/menus", method = RequestMethod.POST)
	@ApiOperation(value = "设置角色菜单所属列表", httpMethod = "POST", notes = "设置角色菜单所属列表", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<Boolean>> setRoleMenus(
			@ApiParam(required = true, name = "roleId", value = "角色ID") @PathVariable("roleId") String roleId,
			@ApiParam(required = true, name = "menus", value = "角色列表") @RequestParam(name = "menus", required = true) List<String> menus) {
		try {
			return ControllerResult.success(authService.setRoleMenus(roleId, menus));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/user/roles", method = RequestMethod.GET)
	@ApiOperation(value = "获取用户角色所属列表", httpMethod = "GET", notes = "获取用户角色所属列表", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<List<UserRoleVo>>> getUserRoles(HttpServletRequest request) {
		try {
			String userId = authService.loadCurrentUserId(ControllerResult.currentTokenId(request), ControllerResult.currentSecretKey(request));
			return ControllerResult.success(authService.getUserRoles(userId));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/{roleId}/menus", method = RequestMethod.GET)
	@ApiOperation(value = "获取角色菜单所属列表", httpMethod = "GET", notes = "获取角色菜单所属列表", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<List<RoleMenuVo>>> getRoleMenus(
			@ApiParam(required = true, name = "roleId", value = "角色ID") @PathVariable("roleId") String roleId) {
		try {
			return ControllerResult.success(authService.getRoleMenus(roleId));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/user/menus", method = RequestMethod.PATCH)
	@ApiOperation(value = "获取用户所属菜单列表", httpMethod = "PATCH", notes = "获取用户所属菜单列表", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<List<UserMenuVo>>> getUserMenus(HttpServletRequest request) {
		try {
			String userId = null;
			if (!manageProperties.getAuthor().isDevAuthEnable()) {
				userId = authService.loadCurrentUserId(ControllerResult.currentTokenId(request), ControllerResult.currentSecretKey(request));
			}
			return ControllerResult.success(authService.loadUserMenus(userId));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}

	@RequestMapping(value = "/client/heartbeat", method = RequestMethod.PATCH)
	@ApiOperation(value = "客户端心跳检查", httpMethod = "PATCH", notes = "返回客户端当前登陆状态是否正常,不正常则提示客户端重新登陆", tags = MODULE_TAG_NAME)
	public ResponseEntity<ServerResponse<AuthUserTokenVo>> clientHeartbeat(HttpServletRequest request) {
		try {
			return ControllerResult.success(authService.refreshUserAuthTokenInfo(ControllerResult.currentTokenId(request),
					ControllerResult.currentSecretKey(request), RemoteClientUtil.getPackHost(request)));
		} catch (Exception e) {
			log.error(MODULE_TAG_NAME, e);
			return ControllerResult.failed(e);
		}
	}
}
